package com.lry.jvm.rtda.heap;

import com.lry.jvm.classfile.constantpool.ConstantMemberRefInfo;
import com.lry.jvm.util.Util;

public class MethodRef extends MemberRef {

    private JMethod method;

    public MethodRef(RuntimeConstantPool rcp, ConstantMemberRefInfo memberRefInfo){
        super(memberRefInfo);
        this.setRcp(rcp);
    }


    public JMethod resolvedMethod(){
        if(null==method){
            resolveMethodRef();
        }
        return method;
    }

    private void resolveMethodRef() {
        //类D想通过方法符号引用访问类C的某个方法
        JClass d = getRcp().getJClass();
        JClass c = resolvedClass();
        if(c.isInterface()){
            Util.panic("java.lang.IncompatibleClassChangeError");
        }

        JMethod lkMethod = lookupMethod(c,getName(),getDescriptor());

        if (lkMethod == null) {
            Util.panic("java.lang.NoSuchMethodError");
        }
        if (!lkMethod.isAccessibleTo(d)) {
            Util.panic("java.lang.IllegalAccessError");
        }
        method = lkMethod;
    }

    public JMethod lookupMethod(JClass c,String name,String descriptor){
        JMethod method = MethodLookup.lookupMethodInClass(c,name,descriptor);
        if(null==method){
            method = MethodLookup.lookupMethodInInterfaces(c.getInterfaces(),name,descriptor);
        }
        return method;
    }



    public JMethod getMethod() {
        return method;
    }

    public void setMethod(JMethod method) {
        this.method = method;
    }
}
